package com.eleadmin.common.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eleadmin.common.core.web.PageParam;
import com.eleadmin.common.core.exception.BusinessException;
import com.eleadmin.common.core.web.PageResult;
import com.eleadmin.common.system.entity.*;
import com.eleadmin.common.system.mapper.UserMapper;
import com.eleadmin.common.system.param.CreditRatingParam;
import com.eleadmin.common.system.param.UserParam;
import com.eleadmin.common.system.service.*;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户Service实现
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private RoleMenuService roleMenuService;
    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Resource
    private UserAddressService userAddressService;

    @Resource
    private CreditRatingService creditRatingService;

    @Override
    public PageResult<User> pageRel(UserParam param) {
        PageParam<User, UserParam> page = new PageParam<>(param);
        page.setDefaultOrder("create_time desc");
        List<User> list = baseMapper.selectPageRel(page, param);
        // 查询用户的角色
        selectUserRoles(list);
        // 查询用户收获地址
        selectUserAddress(list);
        return new PageResult<>(list, page.getTotal());
    }


    @Override
    public PageResult<User> pageRelS(UserParam param) {
        PageParam<User, UserParam> page = new PageParam<>(param);
        page.setDefaultOrder("create_time desc");
        List<User> list = baseMapper.selectPageRel(page, param);
        // 查询用户的角色
        selectUserRoles(list);
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public PageResult<User> pageRelT(UserParam param) {
        PageParam<User, UserParam> page = new PageParam<>(param);
        page.setDefaultOrder("create_time desc");
        List<User> list = baseMapper.selectPageRel(page, param);
        // 查询用户的角色
        selectUserRoles(list);
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public List<User> listRel(UserParam param) {
        List<User> list = baseMapper.selectListRel(param);
        // 查询用户的角色
        selectUserRoles(list);
        // 排序
        PageParam<User, UserParam> page = new PageParam<>(param);
        page.setDefaultOrder("create_time desc");
        return page.sortRecords(list);
    }

    @Override
    public User getByIdRel(Integer userId) {
        UserParam param = new UserParam();
        param.setUserId(userId);
        User user = param.getOne(baseMapper.selectListRel(param));
        if (user != null) {
            user.setRoles(userRoleService.listByUserId(user.getUserId()));
            user.setAuthorities(roleMenuService.listMenuByUserId(user.getUserId(), null));
            user.setAddressList(userAddressService.listByUserIds(Collections.singletonList(user.getUserId())));
        }
        return user;
    }

    @Override
    public User getByUsername(String username) {
        if (StrUtil.isBlank(username)) {
            return null;
        }
        User user = baseMapper.selectByUsername(username);
        if (user != null) {
            user.setRoles(userRoleService.listByUserId(user.getUserId()));
            user.setAuthorities(roleMenuService.listMenuByUserId(user.getUserId(), null));
        }
        return user;
    }

    @Override
    public User getByUsernameType(String username,String type) {
        if (StrUtil.isBlank(username) || StrUtil.isBlank(type)) {
            return null;
        }
        User user = baseMapper.selectByUsernameType(username,type);
        if (user != null) {
            user.setRoles(userRoleService.listByUserId(user.getUserId()));
            user.setAuthorities(roleMenuService.listMenuByUserId(user.getUserId(), null));
        }
        return user;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return getByUsername(username);
    }

    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.SERIALIZABLE)
    @Override
    public boolean saveUser(User user) {
        if (StrUtil.isNotEmpty(user.getUsername()) && baseMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, user.getUsername())) > 0) {
            throw new BusinessException("账号已存在");
        }
        if (StrUtil.isNotEmpty(user.getPhone()) && baseMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getPhone, user.getPhone())) > 0) {
            throw new BusinessException("手机号已存在");
        }
        if (StrUtil.isNotEmpty(user.getEmail()) && baseMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getEmail, user.getEmail())) > 0) {
            throw new BusinessException("邮箱已存在");
        }
        boolean result = baseMapper.insert(user) > 0;
        if (result && user.getRoles() != null && user.getRoles().size() > 0) {
            List<Integer> roleIds = user.getRoles().stream().map(Role::getRoleId).collect(Collectors.toList());
            if (userRoleService.saveBatch(user.getUserId(), roleIds) < roleIds.size()) {
                throw new BusinessException("用户角色添加失败");
            }
        }
        if (result && user.getAddressList() != null && user.getAddressList().size() > 0) {
            userAddressService.remove(new LambdaUpdateWrapper<UserAddress>().eq(UserAddress::getUserId, user.getUserId()));
            //循环设置手机号
            for (UserAddress userAddress : user.getAddressList()) {
                userAddress.setPhone(user.getPhone());
            }
            if (!userAddressService.saveBatch(user.getAddressList())) {
                throw new BusinessException("用户收获地址添加失败");
            }
        }
        //添加信用等级
        CreditRating creditRating = new CreditRating();
        creditRating.setUserId(user.getUserId());
        creditRating.setCreditRating("优秀");
        creditRating.setCreditRatingScore(100);
        creditRatingService.save(creditRating);

        return result;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public boolean updateUser(User user) {
        if (StrUtil.isNotEmpty(user.getUsername()) && baseMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, user.getUsername())
                .ne(User::getUserId, user.getUserId())) > 0) {
            throw new BusinessException("账号已存在");
        }
        if (StrUtil.isNotEmpty(user.getPhone()) && baseMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getPhone, user.getPhone())
                .ne(User::getUserId, user.getUserId())) > 0) {
            throw new BusinessException("手机号已存在");
        }
        if (StrUtil.isNotEmpty(user.getEmail()) && baseMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getEmail, user.getEmail())
                .ne(User::getUserId, user.getUserId())) > 0) {
            throw new BusinessException("邮箱已存在");
        }
        boolean result = baseMapper.updateById(user) > 0;
        if (result && user.getRoles() != null && user.getRoles().size() > 0) {
            userRoleService.remove(new LambdaUpdateWrapper<UserRole>().eq(UserRole::getUserId, user.getUserId()));
            List<Integer> roleIds = user.getRoles().stream().map(Role::getRoleId).collect(Collectors.toList());
            if (userRoleService.saveBatch(user.getUserId(), roleIds) < roleIds.size()) {
                throw new BusinessException("用户角色添加失败");
            }
        }
        // 设置用户地址
        if (result && user.getAddressList() != null && user.getAddressList().size() > 0) {
            userAddressService.remove(new LambdaUpdateWrapper<UserAddress>().eq(UserAddress::getUserId, user.getUserId()));
            if (!userAddressService.saveBatch(user.getAddressList())) {
                throw new BusinessException("用户收获地址添加失败");
            }
        }
        return result;
    }

    @Override
    public boolean comparePassword(String dbPassword, String inputPassword) {
        return bCryptPasswordEncoder.matches(inputPassword, dbPassword);
    }

    @Override
    public String encodePassword(String password) {
        // bCryptPasswordEncoder.encode 这个是具体加密方法，入参password是明文，反参就是加密后的密文
        return password == null ? null : bCryptPasswordEncoder.encode(password);
    }

    /**
     * 批量查询用户的角色
     *
     * @param users 用户集合
     */
    private void selectUserRoles(List<User> users) {
        if (users != null && users.size() > 0) {
            List<Integer> userIds = users.stream().map(User::getUserId).collect(Collectors.toList());
            List<Role> userRoles = userRoleService.listByUserIds(userIds);
            for (User user : users) {
                List<Role> roles = userRoles.stream().filter(d -> user.getUserId().equals(d.getUserId()))
                        .collect(Collectors.toList());
                user.setRoles(roles);
            }
        }
    }

    private void selectUserAddress(List<User> users) {
        if (users != null && users.size() > 0) {
            List<Integer> userIds = users.stream().map(User::getUserId).collect(Collectors.toList());
            List<UserAddress> userAddresses = userAddressService.listByUserIds(userIds);
            for (User user : users) {
                List<UserAddress> addresses = userAddresses.stream().filter(d -> user.getUserId().equals(d.getUserId()))
                        .collect(Collectors.toList());
                user.setAddressList(addresses);
            }
        }
    }


	@Override
	public List<UserVo>  listRelForEchart(UserParam param) {
		List<UserVo> list = baseMapper.listRelForEchart();
		return list;
	}


	@Override
	public List<UserVo> orderTypelistRelForEchart(UserParam param) {
		List<UserVo> list = baseMapper.orderTypelistRelForEchart();
		return list;
	}
	
	@Override
	public List<UserVo> annolistRelForEchart(UserParam param) {
		List<UserVo> list = baseMapper.annolistRelForEchart();
		return list;
	}


	@Override
	public List<UserVo> starlistRelForEchart(UserParam param) {
		List<UserVo> list = baseMapper.starlistRelForEchart();
		return list;
	}

	@Override
	public List<UserVo> orderlistRelForEchart(UserParam param) {
		List<UserVo> list = baseMapper.orderlistRelForEchart();
		return list;
	}

	@Override
	public List<UserVo> statuslistRelForEchart(UserParam param) {
		List<UserVo> list = baseMapper.statuslistRelForEchart();
		return list;
	}

}
